package com.example.teacher.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.example.teacher.R;
import com.example.teacher.SignalingClient;
import com.example.teacher.SignalingClient2;
import com.example.teacher.adpter.PeerConnectionAdapter;
import com.example.teacher.adpter.SdpAdapter;
import com.example.teacher.network.ReceivedCookiesInterceptor;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import org.json.JSONObject;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/*
* 学生考试界面
* */
public class StudentActivity extends RxAppCompatActivity implements SignalingClient2.Callback , View.OnClickListener {

    private RelativeLayout  bottom_rl;
   private ImageView close_open;
    EglBase.Context eglBaseContext;
    PeerConnectionFactory peerConnectionFactory;
    SurfaceViewRenderer localView;
    MediaStream mediaStream;
    List<PeerConnection.IceServer> iceServers;
    public HashMap<String, PeerConnection> peerConnectionMap;
    SurfaceViewRenderer[] remoteViews;
    int remoteViewsIndex = 0;
    final int ALL_PERMISSIONS_CODE = 1;
    private static  String TAG="SignalingClient2222";
    private AudioManager audioManager;
    /*    private  AudioSource audioSource;
        private  AudioTrack localAudioTrack;*/
    private  MediaConstraints audioConstraints;
    private static int currVolume = 0;
    private  boolean isSpeak=true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_student_exams);
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        //初始化界面
        invite();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, Manifest.permission.MODIFY_AUDIO_SETTINGS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO,Manifest.permission.MODIFY_AUDIO_SETTINGS}, ALL_PERMISSIONS_CODE);
        } else {
            // all permissions already granted
            start();
        }
        // OpenSpeaker();
    }
    private void invite(){
        bottom_rl=(RelativeLayout)findViewById(R.id.bottom_rl);
        close_open=(ImageView) findViewById(R.id.close_open);
        close_open.setOnClickListener(this);
     //   bottom_rl.setBackgroundColor(Color.TRANSPARENT);
      bottom_rl.getBackground().setAlpha(20);


    }
    //打开扬声器
    @SuppressLint({"NewApi", "WrongConstant"})
    public void OpenSpeaker() {
        isSpeak=true;
        try {
            audioManager.setMode(AudioManager.ROUTE_SPEAKER);
            // 获取当前通话音量
            if (!audioManager.isSpeakerphoneOn()) {
                audioManager.setSpeakerphoneOn(true);
                audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
                        AudioManager.STREAM_VOICE_CALL);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d("audioManager",audioManager.isMicrophoneMute()+"")
        ;
    }
    //关闭扬声器
    public void CloseSpeaker() {
        isSpeak=false;
        try {
            if(audioManager != null) {
                if(audioManager.isSpeakerphoneOn()) {
                    audioManager.setSpeakerphoneOn(false);
                    audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,currVolume,
                            AudioManager.STREAM_VOICE_CALL);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //Toast.makeText(context,"揚聲器已經關閉",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.close_open:
                if (isSpeak){
                    CloseSpeaker();
                }else {
                    OpenSpeaker();
                }
                break;


        }
    }
    private void start(){
        //tun:125.88.151.100:3479"s
        peerConnectionMap = new HashMap<>();
        iceServers = new ArrayList<>();

        iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer());
        eglBaseContext = EglBase.create().getEglBaseContext();

        // create PeerConnectionFactory
        PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions
                .builder(this)
                .createInitializationOptions());
        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
        DefaultVideoEncoderFactory defaultVideoEncoderFactory =
                new DefaultVideoEncoderFactory(eglBaseContext, true, true);
        DefaultVideoDecoderFactory defaultVideoDecoderFactory =
                new DefaultVideoDecoderFactory(eglBaseContext);
        peerConnectionFactory = PeerConnectionFactory.builder()
                .setOptions(options)
                .setVideoEncoderFactory(defaultVideoEncoderFactory)
                .setVideoDecoderFactory(defaultVideoDecoderFactory)
                .createPeerConnectionFactory();

        SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBaseContext);
        // create VideoCapturer
        VideoCapturer videoCapturer = createCameraCapturer(true);
        VideoSource videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast());




        videoCapturer.initialize(surfaceTextureHelper, getApplicationContext(), videoSource.getCapturerObserver());
        videoCapturer.startCapture(480, 640, 30);

        localView = findViewById(R.id.localView);
        localView.setMirror(true);
        localView.init(eglBaseContext, null);

        // create VideoTrack
        VideoTrack videoTrack = peerConnectionFactory.createVideoTrack("100", videoSource);
//        // display in localView
        videoTrack.addSink(localView);


        audioConstraints = new MediaConstraints();
      /*  audioSource = peerConnectionFactory.createAudioSource(audioConstraints);
        localAudioTrack = peerConnectionFactory.createAudioTrack("101", audioSource);
        localAudioTrack.setEnabled(true);*/



        remoteViews = new SurfaceViewRenderer[]{
                findViewById(R.id.remoteView),
                findViewById(R.id.remoteView2),
                findViewById(R.id.remoteView3),
        };

        for(SurfaceViewRenderer remoteView : remoteViews) {
            remoteView.setMirror(false);
           // remoteView.getBackground().setAlpha(100);
            remoteView.init(eglBaseContext, null);
        }



        mediaStream = peerConnectionFactory.createLocalMediaStream("mediaStream");
        mediaStream.addTrack(videoTrack);
        //   mediaStream.addTrack(localAudioTrack);
        SignalingClient2.get().init(this);


    }
    @Override
    public void CreatePeerConnnect(String str) {
        //子线程创建连接
   /*     new Thread(new Runnable() {
        @Override
        public void run() {
        getOrCreatePeerConnection(str);
        }
       }).start();*/

        getOrCreatePeerConnection(str);
    }
    private synchronized PeerConnection getOrCreatePeerConnection(String socketId) {

        PeerConnection peerConnection = peerConnectionFactory.createPeerConnection(iceServers, new PeerConnectionAdapter("PC:" + socketId) {
            @Override
            public void onIceCandidate(IceCandidate iceCandidate) {
                super.onIceCandidate(iceCandidate);
                SignalingClient2.get().sendIceCandidate(iceCandidate, socketId);
                Log.d(TAG,"111111");
            }

            @Override
            public void onAddStream(MediaStream mediaStream) {
                super.onAddStream(mediaStream);
                VideoTrack remoteVideoTrack = mediaStream.videoTracks.get(0);
                runOnUiThread(() -> {
                    remoteVideoTrack.addSink(remoteViews[remoteViewsIndex++]);
                    Log.d(TAG,"222222");
                });
            }
        });
        peerConnection.connectionState();
        peerConnection.addStream(mediaStream);
        peerConnectionMap.put(socketId, peerConnection);
        return peerConnection;
    }

    @Override
    public void onCreateRoom() {

    }

    @Override
    public void onPeerJoined(String socketId) {
        PeerConnection peerConnection = peerConnectionMap.get(socketId);
        peerConnection.createOffer(new SdpAdapter("createOfferSdp:" + socketId) {
            @Override
            public void onCreateSuccess(SessionDescription sessionDescription) {
                super.onCreateSuccess(sessionDescription);
                peerConnection.setLocalDescription(new SdpAdapter("setLocalSdp:" + socketId), sessionDescription);
                SignalingClient2.get().sendSessionDescription(sessionDescription, socketId);
                Log.d(TAG,"33333");
            }
        }, new MediaConstraints());
    }

    @Override
    public void onSelfJoined() {

    }
    @Override
    public void onLeaveRoom(String msg) {

    }
    @Override
    public void onOfferReceived(JSONObject data) {
        runOnUiThread(() -> {
            JSONObject msg = (JSONObject) data;
            JSONObject d = data.optJSONObject("data");
            String socketId = msg.optString("account");
            PeerConnection peerConnection = peerConnectionMap.get(socketId);
            // Log.d("fgfgg111",peerConnectionMap.size()+"");

            Iterator i = peerConnectionMap.entrySet().iterator();
            while (i.hasNext()) {
                Object obj = i.next();
                String key = obj.toString();
                Log.d("fgfgg111",peerConnectionMap.size()+"  key="+key);
            }


            if(peerConnection!=null){
                try {
                    peerConnection.setRemoteDescription(new SdpAdapter("setRemoteSdp:" + socketId), new SessionDescription(SessionDescription.Type.OFFER, d.optString("sdp")));

                    peerConnection.createAnswer(new SdpAdapter("localAnswerSdp") {
                        @Override
                        public void onCreateFailure(String s) {
                            super.onCreateFailure(s);
                            Log.d("dasdfafdaf111",s);
                        }

                        @Override
                        public void onCreateSuccess(SessionDescription sdp) {
                            super.onCreateSuccess(sdp);
                            sdp = new SessionDescription(SessionDescription.Type.ANSWER,sdp.description);
                            peerConnection.setLocalDescription(new SdpAdapter("setLocalSdp:" + socketId), sdp);
                            SignalingClient2.get().sendSessionDescription(sdp, socketId);
                            Log.d("reyey222",sdp+"==="+socketId);
                            Log.d(TAG,"444444");
                        }
                    }, new MediaConstraints());
                } catch (Exception e) {
                    Log.d("dasdfafdaf222",e.toString());
                    e.printStackTrace();
                }
            }



        });
    }

    @Override
    public void onAnswerReceived(JSONObject data) {
        //子线程Anser
   /*   new Thread(new Runnable() {
      @Override
      public void run() {
          JSONObject msg = (JSONObject) data;
          JSONObject d = data.optJSONObject("data");
          String socketId = msg.optString("account");
          PeerConnection peerConnection = peerConnectionMap.get(socketId);

          Iterator i = peerConnectionMap.entrySet().iterator();
          while (i.hasNext()) {
              Object obj = i.next();
              String key = obj.toString();
              Log.d("fgfgg222",peerConnectionMap.size()+"  key="+key);
          }
          Log.d(TAG,"5555555    "+d.optString("sdp"));
//        String socketId = data.optString("from");
//        PeerConnection peerConnection = getOrCreatePeerConnection(socketId);
          peerConnection.setRemoteDescription(new SdpAdapter(null),
                  new SessionDescription(SessionDescription.Type.ANSWER, d.optString("sdp")));

      }
      }).start();*/
        JSONObject msg = (JSONObject) data;
        JSONObject d = data.optJSONObject("data");
        String socketId = msg.optString("account");
        PeerConnection peerConnection = peerConnectionMap.get(socketId);
        if (peerConnection == null){
            return;
        }
        Iterator i = peerConnectionMap.entrySet().iterator();
        while (i.hasNext()) {
            Object obj = i.next();
            String key = obj.toString();
            Log.d("fgfgg222",peerConnectionMap.size()+"  key="+key);
        }
        peerConnection.setRemoteDescription(new SdpAdapter("setRemoteSdp:" + socketId),
                new SessionDescription(SessionDescription.Type.ANSWER, d.optString("sdp")));
    }

    @Override
    public void onIceCandidateReceived(JSONObject data) {
        Log.d("fdgsgg",data.toString());
        JSONObject msg = (JSONObject) data;
        JSONObject d = data.optJSONObject("data");
        String socketId = msg.optString("account");
        PeerConnection peerConnection = peerConnectionMap.get(socketId);

        Iterator i = peerConnectionMap.entrySet().iterator();
        while (i.hasNext()) {
            Object obj = i.next();
            String key = obj.toString();
            Log.d("fgfgg3333",peerConnectionMap.size()+"  key="+key);
        }
        if (peerConnection != null){
            peerConnection.addIceCandidate(new IceCandidate(
                    d.optString("id"),
                    d.optInt("label"),
                    d.optString("candidate")
            ));}
        Log.d(TAG,"666666");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SignalingClient2.get().destroy();
    }

    private VideoCapturer createCameraCapturer(boolean isFront) {
        Camera1Enumerator enumerator = new Camera1Enumerator(false);
        final String[] deviceNames = enumerator.getDeviceNames();

        // First, try to find front facing camera
        for (String deviceName : deviceNames) {
            if (isFront ? enumerator.isFrontFacing(deviceName) : enumerator.isBackFacing(deviceName)) {
                VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);

                if (videoCapturer != null) {
                    return videoCapturer;
                }
            }
        }
        return null;
    }

}
